|
Technote 1156Scribbling Into AWT ComponentsBy Jens Alfke |
CONTENTSIntroduction to Impure
Drawing |
This Technote
describes how to draw into an AWT Component by means other
than the Java AWT Graphics API. In particular, by
discovering the QuickDraw |
Introduction to Impure DrawingMost Java applications are content (if sometimes grudgingly so) to use normal “100% Pure Java” APIs to draw their user interface. They use a combination of existing AWT control components like Button or Checkbox, and custom Component subclasses that use the graphics primitives provided by the AWT Graphics class to draw themselves. (They may also use components provided by higher-level class libraries such as Swing or IFC, which in turn use Graphics.) However, some Java code needs to use drawing services provided by the platform’s toolbox. Such code will usually be a Java library whose goal is to provide a Java API for features provided by the platform’s toolbox -- Apple’s QuickTime For Java is one such example; another would be an OpenGL interface for Java. Such code will need to use either native methods or
This is an issue that applies to any platform, not just the Mac OS (although the details of the resources necessary are of course platform-specific.) Sun Microsystems, therefore, defined an API collectively referred to as DrawingSurface that can be used to map from a Component object to native-window system resources. |
How To Do ItFirst, use the right kind of Component as your drawing surface. You need a Component with a native peer, so lightweight Components won’t work. And doing your own drawing into components that AWT itself already draws into -- like Button or Choice -- is discouraged. The Component types that work best, then, are Canvas, Panel and any of the Window types (Window, Frame, Dialog.) Getting to the DrawingSurfaceThe interface Here’s a Java snippet that shows how to get the
(You can do the same thing from native code using JNI; it’s just more awkward.) How to DrawYou need to call the To prevent AWT code running on other threads from messing
with the port (or other global Toolbox state) while you’re
drawing, you need to synchronize against the Toolbox
lock before you call the
Now that you've locked the drawing surface, QuickDraw is
all set to draw into the Component. Its You can get the Component’s bounding box in local
coordinate by calling the method
When you’re done drawing, you don’t need to restore the
previous It looks like this, continuing the above snippet:
Accessing the WindowPtrIn some circumstances (e.g., if messing with the
Palette Manager) you may need to find the Mac OS
You get the
Don’t hang onto these values for too long -- they will
not be valid after the Component’s peer has been disposed,
that is, after the Component or a parent is hidden or the
window closed. For safety’s sake you should only get and
access them while the
|
CompatibilityThe The method Not all Java implementations on all platforms support
|
Further References
|
AcknowledgmentsThanks to Bill Stewart, John Burkey, and Nick Kledzik for reviewing this Technote and pointing out omissions, and to Steve Zellers for helping out with the sample code. |